String StringBuilder StringBuffer
1. String类
- 字符串是常量,创建后不可改变。
字符串字面值存储在字符串池中,可以共享。
操作量较少
- 对已赋值的字符串进行重新赋值时,相当于在方法区的字符串池内重新开辟一块空间,并将栈中对应的变量名指向这个空间地址。
String s = "hello
使用这个方法创建字符串将产生一个对象,并在字符串池中存储。使用
new String()
方法创建字符串将产生两个对象,堆、池中各存储一个。并且栈中对象地址会指向堆,而堆在运行时会指向常量池(可能会浪费空间)。
1.1. 常用方法
public int length()
返回字符串长度。public char charAt(int index)
根据下标获取字符。public boolean contains(String str)
判断当前字符串中是否包含str。public char[] toCharArray()
将字符串转换成数组。public int indexOf(String str, int start)
查找str首次出现的下标,存在则返回该下标;不存在则返回-1。start表示开始的下标,可选。
public int lastIndexOf(String str, int start)
查找字符串中最后一次出现的下标的索引。public String trim()
去掉字符串前后的空格。public String toUpperCase()
将小写转成大写。public String toLowerCase()
将大写转成小写。public boolean startWith(String str)
判断字符串是否以str开头。public boolean endWith(String str)
判断字符串是否以str结尾。public String replace(char oldChar, char newChar()
将旧字符串替换成新字符串。public String[] split(String str)
根据str做拆分。public byte[] getBytes()
将字符串转成byte数组。如同时需要多个字符作为分隔符,如下面的例子:
String say = "java is the best,language"; String[] arr = say.split("[ ,]+"); // 使用"[]"包裹所有的分隔符,+号表示可以匹配多个,如多个连续的空格 // 正则表达式 // arr = ["java", "is", "the", "best", "language"]
1.2. 两个字符串比较
equals()比较相等
String s1 = "hello"; String s2 = "HELLO"; s1.equals(s2); // false,区分大小写 s1.equalIgnoreCase(s2); // true,忽略大小写
compareTo()比较大小。如果二者长度一致则,根据字典顺序。两个变量按照字典顺序从第一个字符起进行比较,相同则继续比较后一位,直到差值不为0或全部比较完成为止,返回差值。如果二者长度不一致,则返回二者差值。二者完全一致,则返回0.
compareTo()方法源码
public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; }
用法:
String s3 = "abc"; String s4 = "xyz"; s3.compareTo(s4); // -23 = (97-120) String s1 = "abc"; String s2 = "abcdef"; s1.conpareTo(s2); // -3 = (3-6)
2. StringBuffer(推荐)
- 可变长。
- 多线程数据量较大。
- 效率低安全
- JDK1.0提供。
2.1. 常用方法
append(String str)
追加字符串。toString()
返回字符串。insert(int offset, String str)
插入字符串。offset表示开始插入的索引,str表示要插入的内容。可为所有数据类型。
replace(int start, int end, String str)
替换字符串。start开始索引,end结束索引。左闭右开。
str要替换的字符串。
delete(int start, int end)
删除对应索引处的子字符串,左闭右开。字符串长度也会减小。reverse()
字符串反转。
3. StringBuilder
3.1. 常用方法
和StringBuffer一样。
- 可变长。
- 单线程数据量较大。
- 效率高不安全。
- JDK5.0提供。
4. StringBuffer、StringBuilder和String的区别
- 效率比String高。
- 比String节省内存。
5. 内存分析
- 经过反编译,可以发现String中无变量参与的字符串拼接会进行编译器优化,直接合并成为完整的字符串,然后再常量池中查找,如果第一次没有这个字符串就放进去,如果有就直接从常量池中取。即除了new方法新建的字符串对象,两个不同方式拼接的字符串,只要最终内容相同,那么地址相等。
- String中有变量参与的字符串拼接不会进行编译器优化,不会直接合并。底层的拼接会通过StringBuilder的append()方法完成,最后调用toString转换成String类型。